package com.pocket.insight.base.mql;

import com.pocket.insight.base.mql.conversion.Gbase8sConversion;
import com.pocket.insight.base.mql.conversion.MongoConversion;
import com.pocket.insight.base.mql.detector.SqlConversion;
import com.pocket.insight.base.mql.relation.StatementRelation;
import com.pocket.insight.base.sql.Dialect;
import com.pocket.insight.base.sql.dialect.BaseDialect;
import com.pocket.insight.base.sql.dialect.Gbase8sDialect;
import com.pocket.insight.base.sql.dialect.MongoDialect;
import com.pocket.insight.entity.Dataset;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.tuple.Pair;

import java.util.List;
import java.util.Map;

/**
 * 描述：
 *
 * @author shuize
 * @create 2024/12/6
 */
public interface Conversion {

    TypedVal statementQueryPack(QueryParts queryParts, StatementRelation statementRelation);

    static Conversion createConversion(Dialect dialect) {
        if (dialect instanceof MongoDialect) {
            return (new MongoConversion()).setDialect(dialect);
        }
        if (dialect instanceof Gbase8sDialect) {
            return (new Gbase8sConversion()).setDialect(dialect);
        }

        return (new SqlConversion()).setDialect(dialect);
    }

    TypedVal bracketQueryWithAlias(TypedVal tableQuery, String alias);

    default void updateStatementRelationFieldInfo(Dataset.Field field, String relationAlias) {}

    TypedVal unionQueryPack(List<TypedVal> paramList);

    Pair<TypedVal, String> getQueryForReused(TypedVal query, String alias, String fromAlias, List<String> withUids, Boolean noNeedToReuse, Integer accessCount);

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    class QueryParts {
        public List<TypedVal>        selectVal;
        public TypedVal              whereVal;
        public TypedVal              havingVal;
        public List<TypedVal>        sortVal;
        public TypedVal              from;
        public Long                  offset;
        public Long                  limit;
        public String                alias;
        public Map<String, TypedVal> valMap;
        public Boolean               allAggConstant;
    }

}
